package com.jk1123.dotdog.http;


import java.io.*;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.util.*;

public class HttpServletRequestImpl implements HttpServletRequest {
    private InputStream in;
    /**
     * 请求头
     */
    private Map<String,String> headers=new HashMap<>();
    /**
     * 请求参数
     */
    private Map<String,String[]> params=new HashMap<>();
    /**
     * 请求资源路径
     */
    private String uri;
    //请求方式
    private String method;
    //请求ip地址
    private String remoteAddress;
    private boolean hasParseParameter=false;


    @Override
    public String getHeader(String name) {
        return headers.get(name);
    }
    @Override
    public String getParameter(String name){
        String[] ss = params.get(name);
        return ss==null?null:ss[0];
    }
    @Override
    public String[] getParameterValues(String name){
        return params.get(name);
    }
    @Override
    public Map<String,String[]> getParameterMap(){
        return params;
    }

    @Override
    public String getRemoteAddress() {
        return remoteAddress;
    }

    @Override
    public String getRequestURI() {
        return uri;
    }


    public HttpServletRequestImpl(InputStream in) {
        this.in = in;
        parse();
    }
    private void parse(){
        try {

            //开始解析

            BufferedReader inReader = new BufferedReader(new InputStreamReader(in));
            //第一行是请求行
            String requestLine=inReader.readLine();
            //System.out.println("请求行:"+requestLine);
            //获取请求方式
            method = requestLine.split(" ")[0];
            //获取资源路径
            String resourceURI = requestLine.split(" ")[1];
            //而在资源路径中 有可能包含了请求的参数
            String[] uriAndParams = resourceURI.split("\\?");
            uri=uriAndParams[0];

            //有请求参数 才解析参数
            if(uriAndParams.length>1){
                String paramsStr=resourceURI.split("\\?")[1];
                parseParams(paramsStr);
            }

            //根据不同请求参数调用不同的解析逻辑
            if(HttpMethod.GET.equalsIgnoreCase(method)){
                //System.out.println("get请求");
                get(inReader);
            }else{
                //System.out.println("post请求");
                post(inReader,in);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }


    private void get(BufferedReader inReader) throws IOException {
        String s=null;
        while ((s = inReader.readLine())!=null){
            //System.out.println("解析请求头:"+s);
            //一行行解析请求头
            if(s.equals("")){
                //如果是get请求 读取到这里也就结束了
                break;
            }else{
                String[] headersArray = s.split(": ");
                headers.put(headersArray[0],headersArray[1]);
            }
        }
    }

    private void post(BufferedReader inReader,InputStream in) throws IOException {
        String s=null;
        while ((s = inReader.readLine())!=null){
            //一行行解析请求头
            if(s.equals("")){
                //如果是post请求 读取到这里也就结束了 紧接着也就是 请求体了
                //那么此时 请求头中 必然已经包含了 数据长度了
                int length =Integer.parseInt(headers.get("Content-Length"));
                //这时候我们就不要读取行了
                byte[] bytes = new byte[length];
                in.read(bytes);
                String requestBody = new String(bytes,0,length,"utf-8");
                //放入参数集合中
                parseParams(requestBody);
                break;
            }else{
                String[] headersArray = s.split(": ");
                headers.put(headersArray[0],headersArray[1]);
            }
        }
    }

    private void parseParams(String paramsStr){
        if (paramsStr!=null&&paramsStr.length()>0){
            //我们知道参数格式都是 参数名=参数值&参数名=参数值形式
            //例如 username=xiaoming&password=123&hobby=smoking&hobby=drink&hobby=tangtou
            String[] paramsStrArray = paramsStr.split("&");
            if (paramsStrArray.length>0){
                for (String param : paramsStrArray) {
                    String[] NameAndValue = param.split("=");
                    String paramName=NameAndValue[0];
                    String paramValue= NameAndValue[1];
                    try {
                        paramValue=URLDecoder.decode(NameAndValue[1],"utf-8");
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }


                    mergeParams(paramName,paramValue);
                }
            }
        }

    }

    private void mergeParams(String paramName, String paramValue) {
        //判断之前参数集合是否包含 该名字的参数数组
        if (params.containsKey(paramName)){
            //如果包含 先取出原数组
            String[] SourceParamValues = params.get(paramName);
            //数组新增值
            String[] destParamValues = addAndMerge(SourceParamValues, paramValue);
            //再讲该参数放入参数集合中
            params.put(paramName,destParamValues);

        }else{
            //放在参数集合中
            params.put(paramName,new String[]{paramValue});
        }
    }
    private String[] addAndMerge(String[] sourceArray,String news){
        List<String> list=new ArrayList<>();
        list.addAll(Arrays.asList(sourceArray));
        if (!list.contains(news)) {
            list.add(news);
        }
        return (String[]) list.toArray();
    }





}
